package org.rsbot.injector.adapters;

import org.rsbot.client.Model;
import org.rsbot.client.ModelCapture;
import org.rsbot.injector.data.ModelData;
import org.rsbot.loader.asm.*;

/**
 *
 * @author Nader Sleiman
 */
public class ModelHackAdapter extends ClassAdapter implements Opcodes {

    public ModelHackAdapter(final ClassVisitor cv, ModelData data) {
        super(cv);
        this.md = data;
    }
    private ModelData md;

    class HackModelMethodAdapter extends MethodAdapter {

        private int astore_c;

        public HackModelMethodAdapter(MethodVisitor mv) {
            super(mv);

        }

        @Override
        public void visitVarInsn(int opcode, int var) {
            mv.visitVarInsn(opcode, var);
            if (astore_c >= 1) {
                return;
            }
            if (opcode == ASTORE) {
                astore_c++;
                mv.visitVarInsn(ALOAD, 0);
                mv.visitTypeInsn(NEW, Type.getType(ModelCapture.class).getInternalName());
                mv.visitInsn(DUP);
                mv.visitVarInsn(ALOAD, var);//same as ADSTORE's index
                mv.visitMethodInsn(INVOKESPECIAL, Type.getType(ModelCapture.class).getInternalName(), "<init>", "(" + Type.getType(Model.class).getDescriptor() + ")V");
                mv.visitFieldInsn(PUTFIELD, md.class_name, md.model_field_name, Type.getType(Model.class).getDescriptor());
            }
        }
    }

    @Override
    public MethodVisitor visitMethod(
            final int access,
            final String name,
            final String desc,
            final String signature,
            final String[] exceptions) {
        final MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
        if (name.equals(md.method_name) && desc.equals(md.method_desc)) {
            return new HackModelMethodAdapter(mv);
        }
        return mv;

    }
}
